
/* <<< COPYRIGHT START >>>
 * Copyright 2006-Present OxygenSoftwareLibrary.com
 * Licensed under the GNU Lesser General Public License.
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * @author: Ugorji Dick-Nwoke
 * <<< COPYRIGHT END >>>
 */


package oxygen.tool.wlfacade;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import oxygen.tool.facade.FacadeBenignException;
import oxygen.tool.facade.FacadeContext;
import oxygen.util.OxygenUtils;

public class WLFacadeContextHelper {
  /** should be anything except "/", since that is the mbean separator */
  public static final String TYPE_NAME_SEP = "=";

  public static final int CONNECTED = OxygenUtils.makeFlag(1);
  public static final int ADMINSERVER = OxygenUtils.makeFlag(2);

  public static final int CHANGE = OxygenUtils.makeFlag(5);
  
  public static final int PRIMARYDOMAIN = OxygenUtils.makeFlag(6);
  public static final int DOMAINROOT = OxygenUtils.makeFlag(7);

  public static final String VAR_SHOWPROMPT = "showprompt";
  public static final String VAR_SHOWSTACKTRACE = "showstacktrace";
  public static final String VAR_FAILONERROR = "failonerror";
  public static final String VAR_TRACEOUTPUT = "traceoutput";
  public static final String VAR_RECORDTOFILE = "recordtofile";
  
  //private static String PRIMARYDOMAIN_HDLR = "PRIMARYDOMAIN_HDLR";
  //private static String GENERICDOMAIN_HDLR = "GENERICDOMAIN_HDLR";
  
  private static String KEY_WLSCRIPTCONNECTION = "KEY_WLSCRIPTCONNECTION";
  private static String KEY_WLCONNECTIONDATA = "KEY_WLCONNECTIONDATA";
  //private static String KEY_CMO = "KEY_CMO";
  //private static String KEY_PREVCMO = "KEY_PREVCMO";
  //private static String KEY_DOMAINNAME = "KEY_DOMAINNAME";
  //private static String KEY_MBEANSERVERNAME = "KEY_MBEANSERVERNAME";
  //private static String KEY_WLJMXHANDLER = "KEY_WLJMXHANDLER";
  
  private static String KEY_CURRENTTREENAME = "KEY_CURRENTTREENAME";
  private static String KEY_TREES = "KEY_TREES";
  
  private FacadeContext ctx;
  
  public WLFacadeContextHelper(FacadeContext _ctx) {
    ctx = _ctx;
    if(getWLConnectionData() == null) {
      ctx.setAttribute(KEY_WLCONNECTIONDATA, new WLConnectionData());
    }
    //do not blankly set attributes in here, since this is just a wrapper around FacadeContext
  }
  
  public FacadeContext getFacadeContext() {
    return ctx;
  }
  
  public WLConnectionData getWLConnectionData() {
    return (WLConnectionData)ctx.getAttribute(KEY_WLCONNECTIONDATA);
    //return getConnection().getWLConnectionData().copy();
  }
  
  public WLScriptConnection getConnection() {
    //System.out.println("ctx.getAttributes(): " + ctx.getAttributes());
    WLScriptConnection wlconn = (WLScriptConnection)ctx.getAttribute(KEY_WLSCRIPTCONNECTION);
    //System.out.println("ctx.getAttributes(): " + ctx.getAttributes());
    //System.out.println("wlconn: " + wlconn);
    return wlconn;
  }
  
  public void connectTo(WLConnectionData wlconndata) throws Exception {
    WLScriptConnectionImpl wlconn = new WLScriptConnectionImpl(wlconndata);
    ctx.setAttribute(KEY_WLSCRIPTCONNECTION, wlconn);
    ctx.setAttribute(KEY_WLCONNECTIONDATA, wlconndata);
    ctx.setFlag(CONNECTED);
    if(wlconn.isAdminServer()) {
      ctx.setFlag(ADMINSERVER);
    } 
    Map m = wlconn.getAllMBS();
    for(Iterator itr = m.keySet().iterator(); itr.hasNext(); ) {
      String s = (String)itr.next();
      Object mbs = m.get(s);
      WLMBSTree wltree = new WLMBSTree(s, mbs, this);
      addTree("mbs:" + s, wltree);
    }
    WLJNDITree wltree = new WLJNDITree(wlconn.getInitialContext(), this);
    addTree("jndi", wltree);
    switchTree("mbs:local");
  }
  
  public void addTree(String key, WLTree wltree) {
    Map trees = (Map)ctx.getAttribute(KEY_TREES);
    if(trees == null) {
      trees = new HashMap();
    }
    trees.put(key, wltree);
    ctx.setAttribute(KEY_TREES, trees);
  }
  
  public void switchTree(String s) throws Exception {
    if(getTree(s) == null) {
      throw new FacadeBenignException("There is no tree by the name: " + s);
    }
    ctx.setAttribute(KEY_CURRENTTREENAME, s);
  }
  
  public Map getTrees() {
    return (Map)ctx.getAttribute(KEY_TREES);
  }
  
  public WLTree getTree(String s) {
    return (WLTree)(getTrees().get(s));
  }
  
  public WLTree getCurrentTree() {
    WLTree wltree = null;
    String s = (String)ctx.getAttribute(KEY_CURRENTTREENAME);
    Map trees = (Map)ctx.getAttribute(KEY_TREES);
    if(s != null && trees != null) {
      wltree = (WLTree)trees.get(s);
    }
    return wltree;
  }
  
  public void disconnect() throws Exception {
    if(!ctx.isFlagSet(CONNECTED)) {
      return;
    }
    //remove all the trees set up in here
    Map trees = (Map)ctx.getAttribute(KEY_TREES);
    if(trees != null) {
      for(Iterator itr = new HashSet(trees.keySet()).iterator(); itr.hasNext(); ) {
        String s = (String)itr.next();
        if(s.startsWith("mbs:") || s.startsWith("jndi")) {
          trees.remove(s);
        }
      }
    }
    //wlconn = null;
    getConnection().close();
    ctx.setAttribute(KEY_WLSCRIPTCONNECTION, null);
    
    // just clear every state
    ctx.clearFlag(PRIMARYDOMAIN);
    ctx.clearFlag(DOMAINROOT);
    ctx.clearFlag(CONNECTED);
    ctx.clearFlag(ADMINSERVER);
    
  }
  
  public String[] getSetStates() {
    ArrayList al = new ArrayList();
    if(ctx.isFlagSet(CONNECTED)) {
      al.add("CONNECTED ");
    }
    if(ctx.isFlagSet(PRIMARYDOMAIN)) {
      al.add("PRIMARYDOMAIN ");
    }
    if(ctx.isFlagSet(ADMINSERVER)) {
      al.add("ADMINSERVER ");
    }
    return (String[])al.toArray(new String[0]);
  }
  
  public String[] getSupportedVars() {
    ArrayList al = new ArrayList();
    al.add(VAR_SHOWPROMPT);
    al.add(VAR_SHOWSTACKTRACE);
    al.add(VAR_FAILONERROR);
    al.add(VAR_TRACEOUTPUT);
    al.add(VAR_RECORDTOFILE);
    return (String[])al.toArray(new String[0]);
  }
  
  public String getPrompt() throws Exception {
    String prompt = "[NO TREE]: > ";
    if(getCurrentTree() != null) {
      prompt = getCurrentTree().getPrompt();
    }
    return prompt;
  }
  
}

